package com.qitianyong.selfclass;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.storage.StorageManager;

import android.os.storage.StorageVolume;
import android.support.v4.provider.DocumentFile;
import android.text.TextUtils;
import android.util.Log;

import com.gkusbsdk.GKUSBCommand;
import com.gkusbsdk.GKUSBSDK;
import com.gkusbsdk.GKUSBTime;
import com.ligo.log.util.ZyLog;
import com.qitianyong.event.MessageEvent;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import static com.qitianyong.selfclass.CustomApp.handler;

import org.greenrobot.eventbus.EventBus;


/**
 * Created by gy on 2017/5/18.
 */

public class FindDeviceThread {
    public static final int OPEN_APP = 1;
    public static final int SYNC_TIME = 2;
    public static final long RECONNECT_DEV_TIME_LIMIT = 5000;
    static FindDeviceThread findDeviceThread;
    private static boolean canUseDevVideo;

    public static long lastConnectTime = 0;

    private static String usbPath = "";


    private static final String TAG = "GKDevice";

    public synchronized static FindDeviceThread getInstance() {
        if (findDeviceThread == null) {
            findDeviceThread = new FindDeviceThread();
        }
        return FindDeviceThread.findDeviceThread;
    }

    private FindDeviceThread() {
        new Thread(FindDeviceRunnable).start();
    }

    private static boolean hasVsFile(String path) {
        File dirFile = new File(path);
        if (dirFile.isDirectory()) {
            File[] files = dirFile.listFiles();
            if (files != null) {
                for (File files1 : files) {
//                    Log.d(TAG,"fileName:"+files1.getName());
                    if (files1.isFile() && files1.getName().contains("vsfile")) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public static List<String> getUsbPaths(Context cxt) {
        List<String> usbPaths = new ArrayList<>();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            File[] externalFiles = CustomApp.customApp.getExternalFilesDirs(Environment.DIRECTORY_DOCUMENTS);
            if (externalFiles != null) {
                for (File file : externalFiles) {
                    if (Environment.isExternalStorageRemovable(file)) {
                        Log.d(TAG, "path= " + file.getPath() + "-> permission : canRead is " + file.canRead() + " canWrite is " + file.canWrite());
                        if (file.canWrite() && file.canRead()) {
                            usbPaths.add(file.getPath());
//                            writeTest(file.getPath());
                        } else {
//                            EventBus.getDefault().post(new MessageEvent(MessageEvent.REQUEST_PERMISSION, ""));
                        }
                    }
                }
            }

            try {

                StorageManager storageManager = (StorageManager) CustomApp.customApp.getSystemService(Context.STORAGE_SERVICE);
                Class storeManagerClazz = Class.forName("android.os.storage.StorageManager");
                Method getVolumesMethod = storeManagerClazz.getMethod("getVolumes");
                List volumeInfos = (List) getVolumesMethod.invoke(storageManager);
                Class volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo");
                Field udiskPath = volumeInfoClazz.getDeclaredField("internalPath");
                Method getFsUuidMethod = volumeInfoClazz.getMethod("getFsUuid");
                if (volumeInfos != null) {
                    for (Object volumeInfo : volumeInfos) {
                        String uuid = (String) getFsUuidMethod.invoke(volumeInfo);
                        if (uuid != null) {
                            String sUdiskPath = (String) udiskPath.get(volumeInfo); // 结果是 /mnt/media_rw/28BA-794A
                            sUdiskPath = sUdiskPath.replace("/mnt/media_rw", "/storage");
                            Log.d(TAG, "sUdiskPath=" + sUdiskPath);
//                            usbPaths.add(sUdiskPath);
                            writeTest(sUdiskPath);
                        }

                    }

                }

            } catch (Exception e) {
                e.printStackTrace();
            }


        } else {
            try {
                StorageManager srgMgr = (StorageManager) cxt.getSystemService(Context.STORAGE_SERVICE);
                Class<StorageManager> srgMgrClass = StorageManager.class;
                String[] paths = (String[]) srgMgrClass.getMethod("getVolumePaths").invoke(srgMgr);
                if (paths != null) {
                    for (String path : paths) {
                        Object volumeState = srgMgrClass.getMethod("getVolumeState", String.class).invoke(srgMgr, path);
                        if (!path.contains("emulated") && Environment.MEDIA_MOUNTED.equals(volumeState)) {
                            usbPaths.add(path);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return usbPaths;

    }


    private static void writeTest(String path) {
        try {
            File dir = new File(path);
            Log.d(TAG, "file=" + dir.canRead() + "      " + dir.canWrite());
            File file = new File(path, "test.txt");

            FileOutputStream outputStream = new FileOutputStream(file);
            outputStream.write("hahahahhadsddds".getBytes());
            outputStream.flush();
            outputStream.close();

            StringBuilder content = new StringBuilder();
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = null;

            while ((line = br.readLine()) != null) {
                content.append(line);
            }


            Log.d(TAG, "content=" + content.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static boolean checkPermission(String path) {
        boolean b = true;
        DocumentFile documentFile = DocumentFile.fromFile(new File(path));
        b = documentFile.canWrite();
        String s = path + "  can write is " + b;
        Log.d(TAG, s);
        return b;
    }

    public static int intent = 0;

    public void setIntent(int intent) {
        this.intent = intent;
        beginSearchDevices = true;
        FindDeviceThread.lastConnectTime = 0;
    }

    private static boolean beginSearchDevices = false;

    private static Runnable FindDeviceRunnable = new Runnable() {
        @Override
        public void run() {
//            if (System.currentTimeMillis() > 1701273600000L) {
//                return;
//            }
            beginSearchDevices = true;

            try {
                if (beginSearchDevices && (GKDevice.__hDevice == 0)) {
      /*                  ArrayList<UsbDevice> matchingHostDevicess = null;
                        try {
                            matchingHostDevicess = UsbDeviceFilter.getMatchingHostDevices(CustomApp.customApp, R.xml.device_filter);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (matchingHostDevicess == null || matchingHostDevicess.size() == 0) {
                            beginSearchDevices = false;
                            ZyLog.d("isGKUSBDevice:" + false);
                            LogUtils.addLog("isGKUSBDevice:" + false);
                            continue;
                        }
                        LogUtils.addLog("beginSearchDevices =" + beginSearchDevices);
                        */
                    ZyLog.d("beginSearchDevices");

                    SharedPreferences config = CustomApp.customApp.getSharedPreferences("config", 0);
                    boolean canUseDevVideo = config.getBoolean("canUseDevVideo", false);
                    int time = canUseDevVideo ? 15 : 3;
                    //for (int j = 0; j < time && beginSearchDevices; j++) {
                    while (beginSearchDevices) {
                        //                        USB[] usb = new USB[32];
                        //                        int count = GKUSBSDK.GKUSB_SearchVideoNodeCams(usb);
                        //count = 1;
                        //                        ZyLog.d("GKUSB_SearchVideoNodeCams count=" + count);
                        //                        for (int i = 0; i < count && beginSearchDevices; i++) {
                        //upgradeRootPermission(i);
                        //upgradeRootPermissionVs1(1);
                        //upgradeRootPermissionVs2(2);
                        //long hDevice = GKUSBSDK.GKUSB_CreateVideoNodeCam(usb[i]);  //20230920.deyue mark
                        try {
                            List<String> pathList = getUsbPaths(CustomApp.customApp);
                            if (pathList.size() > 0) {
                                usbPath = pathList.get(0);
                            }
                            Log.d(TAG, "diskUsbPath=" + usbPath);
                            if (TextUtils.isEmpty(usbPath)) {
                                PublicMethod.sleep(2000);
                                continue;
                            }
                            long hDevice = GKUSBSDK.GKUSB_CreateVideoVsUvcCam(usbPath);
                            Log.d(TAG, "GKUSB_CreateVideoNodeCam =" + hDevice);
                            if (hDevice != 0) {
                                PublicMethod.sleep(500);
                                GKUSBTime usbTime = PublicMethod.CurrentTime2USBTime();
                                Log.i(TAG, "time:" + usbTime.__year + "-" + usbTime.__month + "-" + usbTime.__day +
                                        " " + usbTime.__hour + ":" + usbTime.__minute + ":" + usbTime.__second);
                                int ret = GKUSBSDK.GKUSB_SetParam(hDevice, GKUSBCommand.CMD_SYNC_TIME, usbTime);
                                Log.i(TAG, "Sync time result" + ret);
                                if (ret == 0) {
                                    PublicMethod.sleep(500);
                                    ret = GKUSBSDK.GKUSB_SetProtocol(hDevice, GKUSBCommand.PROTOCOL_TYPE.TYPE_NEW);
                                    //ret = 1;
                                    if (ret == 1) {  // 设置成功
                                        GKDevice.__hDevice = hDevice;
                                        if (!FindDeviceThread.canUseDevVideo) {
                                            FindDeviceThread.canUseDevVideo = true;
                                            config.edit().putBoolean("canUseDevVideo", true).apply();
                                        }
                                        if (intent == OPEN_APP) {
                                            handler.sendEmptyMessageDelayed(0, 500);
                                        }
                                        beginSearchDevices = false;
                                    } else {
                                        GKUSBSDK.GKUSB_Destroy(hDevice);
                                    }
                                    Log.i(TAG, "-----SetProtocol ------ " + ret);
                                } else {
                                    GKUSBSDK.GKUSB_Destroy(hDevice);
                                }
                                PublicMethod.sleep(300);
                            }
                            PublicMethod.sleep(200);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //                        }
                        PublicMethod.sleep(3000);
                    }
    /*

                        if (beginSearchDevices && !FindDeviceThread.canUseDevVideo) {
                            UsbManager usbManager = (UsbManager) CustomApp.customApp.getSystemService(Context.USB_SERVICE);
                            PendingIntent mPermissionIntent = PendingIntent.getBroadcast(CustomApp.customApp, 0, new Intent(ACTION_USB_PERMISSION), 0);
                            ArrayList<UsbDevice> matchingHostDevices = new ArrayList<>();
                            try {
                                matchingHostDevices = UsbDeviceFilter.getMatchingHostDevices(CustomApp.customApp, R.xml.device_filter);
                            } catch (Exception e) {
                            }
                            ZyLog.d("beginUsbDevices matchingHostDevices");
                            for (final UsbDevice usbDevice : matchingHostDevices) {
                                LogUtils.addLog("beginUsbDevices");
                                if (usbManager.hasPermission(usbDevice)) {
                                    ZyLog.d("beginUsbDevices initDevUsbDevice");
                                    USBPermissionRequestResultReceiver.initDevUsbDevice(usbDevice);
                                } else {
                                    ZyLog.d("beginUsbDevices requestPermission");
                                    usbManager.requestPermission(usbDevice, mPermissionIntent);
                                }
                                break;
                            }
                        }
    */

                } else if (beginSearchDevices) {
                    lastConnectTime = System.currentTimeMillis();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            beginSearchDevices = false;
            PublicMethod.sleep(2000);

        }
    };

    public boolean upgradeRootPermission(int num) {
        Process process = null;
        DataOutputStream os = null;
        String cmd = "chmod 777 " + "/dev/video" + num;
        try {
            process = Runtime.getRuntime().exec("su"); //切换到root帐号
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(cmd + "\n");
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
        } catch (Exception e) {
            ZyLog.d("cmd =" + cmd + "  " + e.getMessage());
            return false;
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (Exception e) {
            }
        }
        ZyLog.d("cmd =" + cmd + "  success");
        return true;
    }

    public boolean upgradeRootPermissionVs1(int num) {
        Process process = null;
        DataOutputStream os = null;
        String cmd = "chmod 777 " + "/mnt/udisk3/vsfile";
        try {
            process = Runtime.getRuntime().exec("su"); //切换到root帐号
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(cmd + "\n");
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
        } catch (Exception e) {
            ZyLog.d("cmd =" + cmd + "  " + e.getMessage());
            return false;
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (Exception e) {
            }
        }
        ZyLog.d("cmd =" + cmd + "  success");
        return true;
    }

    public boolean upgradeRootPermissionVs2(int num) {
        Process process = null;
        DataOutputStream os = null;
        String cmd = "chmod 777 " + "/mnt/udisk3/rvsfile";
        try {
            process = Runtime.getRuntime().exec("su"); //切换到root帐号
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(cmd + "\n");
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
        } catch (Exception e) {
            ZyLog.d("cmd =" + cmd + "  " + e.getMessage());
            return false;
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (Exception e) {
            }
        }
        ZyLog.d("cmd =" + cmd + "  success");
        return true;
    }
}
